<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>JSDoc: Source: indexed.js</title>

    <script src="scripts/prettify/prettify.js"> </script>
    <script src="scripts/prettify/lang-css.js"> </script>
    <!--[if lt IE 9]>
      <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    <![endif]-->
    <link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
    <link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
</head>

<body>

<div id="main">

    <h1 class="page-title">Source: indexed.js</h1>

    



    
    <section>
        <article>
            <pre class="prettyprint source linenums"><code>/*
 *  1、配置
 *  2、实例化IDB
 *  3、解释配置、初始化数据库
 *  4、实例化Table
 */

// const INDEXED_DB = {
//   name: 'XdhWeb',
//   version: 1,
//   force: false,
//   tables: {
//     users: [
//       {
//         name: 'id',
//         key: true,
//         increment: true
//       },
//       {
//         name: 'name',
//         index: true
//       },
//       {
//         name: 'age',
//         index: true
//       },
//       {
//         name: 'role',
//         index: true,
//         value: 1
//       },
//       {
//         name: 'intro',
//         value: ''
//       }
//     ]
//   }
// }


import {warn} from './console';
import {guid} from './util'

if (!window.indexedDB) {
  throw new Error('浏览器不支持IndexedDB')
}

const noop = function () {
}

function bindHandlers(instance, success, error) {
  instance.onsuccess = function (e) {
    success(e.target.result)
  }
  instance.onerror = error
}

function handlersPromis(instance) {
  return new Promise((resolve, reject) => {
    bindHandlers(instance, resolve, reject)
  })
}

function open(name, version) {
  const request = window.indexedDB.open(name, version);
  return new Promise((resolve, reject) => {
    request.onupgradeneeded = function (e) {
      resolve({
        type: 'upgrade',
        db: e.target.result
      })
    }
    request.onabort = reject
    bindHandlers(request, function (db) {
      resolve({
        type: 'success',
        db: db
      })
    }, reject)
  })
}


// columns = [{
//   name: '字段名',
//   key: '是否主键',
//   increment: '主键是否递增',
//   guid: '主键是否采用GUID',
//   index: '是否建索引',
//   unique: '值是否唯一',
//   value: '默认值'
// }]
function createTable(db, name, columns) {
  if (db.objectStoreNames.contains(name)) return
  
  // 找到主键配置,如果没有配置主键，默认用 _id 名称设置自增主键, 主键只有一个
  const keyField = columns.find(col => col.key) || {name: '_id', increment: true}
  
  // 索引字段，可以有多个索引
  const indexFields = columns.filter(col => col.index)
  
  const objectStore = db.createObjectStore(name, {
    keyPath: keyField.name,
    autoIncrement: keyField.increment
  })
  
  indexFields.forEach(item => {
    // 索引名称与字段名称相同
    objectStore.createIndex(item.name, item.name, {unique: !!item.unique})
  })
}

function init(idb) {
  const db = idb._db, options = idb._options, tables = options.tables || [];
  
  Object.keys(tables).forEach(name => {
    // 已存在表，将删除，重新建立
    if (db.objectStoreNames.contains(name)) {
      if (options.force) {
        db.deleteObjectStore(name)
        createTable(db, name, tables[name])
      } else {
        warn(`已存在表：${name}, 将忽略该表的创建，建议使用升级处理函数`)
      }
    } else {
      createTable(db, name, tables[name])
    }
    
  })
}

/**
 * 获取表 每个实体的默认值
 * @param schemas
 */
function getDefault(columns) {
  let value = {}
  columns.forEach(col => {
    if (typeof col.value !== 'undefined') {
      value[col.name] = col.value
    }
  })
  return value
}


export class Table {
  constructor(db, name, columns) {
    this._db = db
    this.name = name
    this.columns = columns
    this.defaultValue = {}
    this.keyField = columns.find(col => col.key) || {name: '_id', increment: true}
    this.defaultValue = getDefault(columns)
  }
  
  get() {
  }
  
  add(data) {
    const tick = new Date().getTime()
    const value = {
      _create: tick,
      _update: tick,
      ...this.defaultValue,
      ...data
    }
    if (this.keyField.guid) {
      value[this.keyField.name] = guid()
    }
    const req = this._db.transaction([this.name], 'readwrite')
      .objectStore(this.name)
      .add(value)
    
    return handlersPromis(req)
  }
  
  put() {
  }
  
  patch() {
  }
  
  remove() {
  }
  
  clear() {
  }
  
  query() {
  }
  
  all() {
  }
  
  count() {
  }
}

/*
schemas = {
  tableName: [
    {
      name: '字段名',
      key: '是否主键',
      increment: '主键是否递增',
      guid: '主键是否采用GUID',
      index: '是否建索引',
      unique: '值是否唯一',
      value: '默认值'
    }
  ]
}
*/
export default class IndexedDB {
  constructor(options) {
    this._options = {
      // 数据库名称
      name: 'XdhWeb',
      // 数据库版本号
      version: 1,
      // 数据库结构
      tables: null,
      // 是否暴力升级，为true时，数据库将重置为当前的数据库结构，数据也清空。
      force: false,
      // 自定义升级方法
      upgrade: noop,
      // 数据库建立连接, 并初始化完成时回调
      ready: noop,
      ...options
    }
    this._db = null
    this.open()
  }
  
  // 打开数据库
  open() {
    const o = this._options
    return open(o.name, o.version)
      .then(res => {
        this._db = res.db
        if (res.type === 'upgrade') {
          init(this)
          o.upgrade(this)
        }
        
        Object.keys(o.tables).forEach(name => {
          this[name] = new Table(this._db, name, o.tables[name])
        })
        o.ready(this)
        return res
      })
      .catch(e => warn(e))
  }
  
  // 关闭连接
  close() {
    this._db &amp;&amp; this._db.close()
    this._db = null
  }
  
  // 删除数据库
  destroy() {
    this.close()
    indexedDB.deleteDatabase(this._options.name)
  }
}
</code></pre>
        </article>
    </section>




</div>

<nav>
    <h2><a href="index.html">Home</a></h2><h3>Modules</h3><ul><li><a href="module-utils_ajax.html">utils/ajax</a></li><li><a href="module-utils_axios.html">utils/axios</a></li><li><a href="module-utils_bom.html">utils/bom</a></li><li><a href="module-utils_bus.html">utils/bus</a></li><li><a href="module-utils_console.html">utils/console</a></li><li><a href="module-utils_convert.html">utils/convert</a></li><li><a href="module-utils_cookie.html">utils/cookie</a></li><li><a href="module-utils_crypto.html">utils/crypto</a></li><li><a href="module-utils_date.html">utils/date</a></li><li><a href="module-utils_directives_clipboard.html">utils/directives/clipboard</a></li><li><a href="module-utils_directives_draggable.html">utils/directives/draggable</a></li><li><a href="module-utils_directives_droppable.html">utils/directives/droppable</a></li><li><a href="module-utils_directives_highlight.html">utils/directives/highlight</a></li><li><a href="module-utils_directives_resizable.html">utils/directives/resizable</a></li><li><a href="module-utils_directives_selecttext.html">utils/directives/selecttext</a></li><li><a href="module-utils_dom.html">utils/dom</a></li><li><a href="module-utils_download.html">utils/download</a></li><li><a href="module-utils_events.html">utils/events</a></li><li><a href="module-utils_excel.html">utils/excel</a></li><li><a href="module-utils_hoc.html">utils/hoc</a></li><li><a href="module-utils_lunar.html">utils/lunar</a></li><li><a href="module-utils_messager.html">utils/messager</a></li><li><a href="module-utils_mock.html">utils/mock</a></li><li><a href="module-utils_openlayer.html">utils/openlayer</a></li><li><a href="module-utils_queue.html">utils/queue</a></li><li><a href="module-utils_skin.html">utils/skin</a></li><li><a href="module-utils_socket.html">utils/socket</a></li><li><a href="module-utils_storage.html">utils/storage</a></li><li><a href="module-utils_theme.html">utils/theme</a></li><li><a href="module-utils_tween.html">utils/tween</a></li><li><a href="module-utils_url.html">utils/url</a></li><li><a href="module-utils_util.html">utils/util</a></li></ul><h3>Classes</h3><ul><li><a href="module-utils_directives_draggable-Draggable.html">Draggable</a></li><li><a href="module-utils_directives_droppable-Droppable.html">Droppable</a></li><li><a href="module-utils_directives_resizable-Resizable.html">Resizable</a></li><li><a href="module-utils_events-Events.html">Events</a></li><li><a href="module-utils_messager.html">utils/messager</a></li><li><a href="module-utils_openlayer-Openlayers.html">Openlayers</a></li><li><a href="module-utils_queue-Queue.html">Queue</a></li><li><a href="module-utils_socket.html">utils/socket</a></li><li><a href="ol.source.TileSuperMapRest.html">TileSuperMapRest</a></li></ul><h3>Events</h3><ul><li><a href="module-utils_socket.html#~event:close">close</a></li><li><a href="module-utils_socket.html#~event:error">error</a></li><li><a href="module-utils_socket.html#~event:message">message</a></li><li><a href="module-utils_socket.html#~event:open">open</a></li><li><a href="module-utils_queue-Queue.html#event:complete">complete</a></li><li><a href="module-utils_queue-Queue.html#event:error">error</a></li><li><a href="module-utils_queue-Queue.html#event:success">success</a></li></ul><h3>Global</h3><ul><li><a href="global.html#getDefault">getDefault</a></li></ul>
</nav>

<br class="clear">

<footer>
    Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.5.5</a> on Sat Dec 01 2018 20:51:24 GMT+0800 (China Standard Time)
</footer>

<script> prettyPrint(); </script>
<script src="scripts/linenumber.js"> </script>
</body>
</html>
